package mrdog.captor;

import java.io.IOException;

import mrdog.common.util.StringUtil;

import org.apache.log4j.Logger;

import jpcap.JpcapCaptor;
import jpcap.NetworkInterface;

public class DogCaptor {

	private static PacketPool pool = null;
	
	private static JpcapCaptor pcaptor = null;
	
	private static int CAP_NUM = -1;
	
	private static Logger log = Logger.getLogger(DogCaptor.class);
	
	public static boolean initPacketPool(int capacity) {
		if(capacity < 1) {
			log.error("Cannot init the PacketPool with the given capacity:" + capacity);
			return false;
		}
		if(pool == null) {
			pool = new BlockingPacketPool(capacity);
		}
		log.info("Init PacketPool["+capacity+"].........................OK");
		return true;
	}
	
	public static PacketPool getPacketPool() {
		if(checkPacketPool()) {
			return pool;
		}
		return null;
	}
	
	public static void capDevice(int capnum, String devName) {
		if(StringUtil.isNul(devName)) {
			log.error("Invalid devName of the Network Device." + devName);
		}
		else {
			NetworkInterface device = lookupDevice(devName);
			if(device == null) {
				log.warn("Network Device cannot be found to match the devName of:" + devName);
			}
			else {
				try {
					pcaptor = JpcapCaptor.openDevice(device, 65535, true, 50);
					log.info("Init JpcapCaptor from Device:" + device.name);
					start(capnum);
				} 
				catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void capPtfile(int capnum, String filName) {
		if(StringUtil.isNul(filName)) {
			log.error("Invalid filName of the method capPtfile." + filName);
		}
		else {
			try {
				pcaptor = JpcapCaptor.openFile(filName);
				log.info("Init JpcapCaptor from File:" + filName);
				start(capnum);
			} 
			catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private static boolean checkPacketPool() {
		if(pool == null) {
			log.warn("The PacketPool has not been initialized.");
			return false;
		}
		return true;
	}
	
	private static void start(int capnum) {
		if(checkPacketPool()) {
			if(capnum > 0) {
				CAP_NUM = capnum;
			}
			new Thread(new PacketCaptor(pool, pcaptor, CAP_NUM)).start();
			log.info("Start DogCaptor with the capnum:" + (capnum== -1 ? "non-stop-way":""+capnum));
		}
	}
	
	private static NetworkInterface lookupDevice(String devName) {
		NetworkInterface[] devices = JpcapCaptor.getDeviceList();
		StringBuffer buf = new StringBuffer("Device List:");
		if(devices != null) {
			for(NetworkInterface device : devices) {
				buf.append("      Device:").append(device.name);
				if(devName.equals(device.name)) {
					return device;
				}
			}
		}
		log.warn(buf.toString());
		return null;
	}
}
